/*******************************************************************************
 * 版权：北京润尼尔网络科技有限公司，保留所有版权<br>
 * 版本：v1.0.0<br>
 * 文件：CommandDelete.js<br>
 * 日期：2016年9月20日<br>
 * 作者: 王志远<br>
 * 功能：删除命令<br>
 *
 * 修改记录：<br>
 * 日期 描述 更新功能<br>
 ******************************************************************************/

window.makeNamespace(window, "Rainier.UI.V2");

/**
 * 类型名称：Rainier.UI.V2.CommandDelete<br>
 * 类型功能：删除元件命令<br>
 */
Rainier.UI.V2.CommandDelete = draw2d.command.CommandDelete.extend({
  NAME: "Rainier.UI.V2.CommandDelete",

  /**
   * 函数名称：Rainier.UI.V2.CommandDelete.init<br>
   * 函数功能：构造函数<br>
   * 异常信息：无<br>
   */
  init: function (editPart) {
    this.editPart = editPart;
    this.canvas = this.editPart.getFigure().getCanvas();
    if (this.canvas) {
      this.context = this.canvas.context;
    }
    this.parentPart = this.editPart.getParent();
    this._super(editPart.getFigure());

    this.connList = null;

    /**
     * deleteInfo 定义：{};
     * {
     * 	model 	 :"",
     * 	ports 	 :"",
     * 	deleteConnInfoStack : [
     *		{
     *			connType	:"",
     *			connModel		: {
     *				connection :"",
     *				sourcePort :"",
     *				targetPort :"",
     *			},
     *			sourceModel		:{
     *				jointModel:"",
     *				hybirdPort:"",
     *			},
     *			targetModel		:{
     *				jointModel:"",
     *				hybirdPort:"",
     *			},
     *  	},
     *  	{},
     *  	{},
     * ]
     */
    this.deleteInfo = null;
    this.node = null;
    this.nodeParent = null;
    this.nodeChildren = null;
  },

  /**
   * 函数名称：Rainier.UI.V2.CommandDelete.canExecute<br>
   * 函数功能：判断是否可以删除<br>
   * 参数输入：无<br>
   * 参数输出：无<br>
   * 函数返回：Boolean 是否可删除<br>
   * 异常信息：<br>
   */
  canExecute: function () {
    return this.editPart.getFigure().getCanvas() !== null;
  },

  /**
   * 函数名称：Rainier.UI.V2.CommandDelete.execute<br>
   * 函数功能：执行添加功能<br>
   * 参数输入：无<br>
   * 参数输出：无<br>
   * 函数返回：无<br>
   * 异常信息：无<br>
   */
  execute: function () {
    var _this = this;
    if (this.editPart) {
      var model = this.editPart.getModel();
      var parentModel = this.parentPart.getModel();
      if (model instanceof Rainier.UI.V2.DeviceModel) {
        this.deleteInfo = parentModel.removeChildModel(model);
        var model = this.deleteInfo.model;
        //同步删除树结构
        var id = model.property.modelProperty.id;
        if (id) {
          // _this.node = $("#ul-mindMap").tree('find',id);
          // if(_this.node){
          // 	_this.nodeChildren = $("#ul-mindMap").tree('getChildren',_this.node.target);
          // 	_this.nodeParent = $("#ul-mindMap").tree('getParent',_this.node.target);
          // 	$("#ul-mindMap").tree('remove',_this.node.target);
          // }
          //重新加上目录子节点
          // this.addSubTree(_this.nodeChildren,_this.nodeParent);
          //父节点删除子信息
          var parentId = model.property.modelProperty.parent;
          var parent = this.getModelById(parentId);
          if (parent) {
            var children = parent.property.modelProperty.children;
            if (children) {
              for (var i = 0; i < children.length; i++) {
                var _id = children[i];
                if (_id == id) {
                  var index = children.indexOf(_id);
                  children.splice(index, 1);
                }
              }
            }
          }
        }
      } else if (model instanceof Rainier.UI.V2.ConnectionModel) {
        this.deleteInfo = parentModel.removeConnection(model);
      }
      var className = model.property.modelProperty.typeName;
      this.deleteUsedPart(className);
    }
  },

  /**
   * 函数名称：Rainier.UI.V2.CommandDelete.addSubTree<br>
   * 函数功能：添加子树结构<br>
   * 函数返回：无<br>
   * 异常信息：无<br>
   */
  addSubTree: function (children, parent) {
    var _this = this;
    $.each(children, function (index, nodeChild) {
      var node = $("#ul-mindMap").tree("find", nodeChild.id);
      if (!node) {
        $("#ul-mindMap").tree("append", {
          parent: parent.target,
          data: [
            {
              id: nodeChild.id,
              text: nodeChild.text,
              state: nodeChild.state,
              animate: nodeChild.animate,
            },
          ],
        });
        if (nodeChild.children) {
          var _parent = $("#ul-mindMap").tree("find", nodeChild.id);
          _this.addSubTree(nodeChild.children, _parent);
        }
      }
    });
  },

  /**
   * 函数名称：Rainier.UI.V2.CommandDelete.deleteUsedPart<br>
   * 函数功能：根据addCount的值删除器件展示栏中的器件，若为0，则删除<br>
   * 函数返回：无<br>
   * 异常信息：无<br>
   */
  deleteUsedPart: function (className) {
    if (className) {
      // if(className == "OverThreeTextModelJson" || className === "TextModelJson2" || className === "TextModelJson3"){
      // 	className = "TextModelJson";
      // }
      for (var i = 0; i < data.length; i++) {
        if (className == data[i].className) {
          data[i].addCount -= 1;
          if (data[i].addCount > 0) {
            return;
          } else {
            data.splice(i, 1);
            for (var j = 0; j < usedPartArray.length; j++) {
              if (usedPartArray[j].className == className) {
                usedPartArray.splice(j, 1);
              }
            }
          }
        }
      }
    }
    // console.log(data);
    // console.log(usedPartArray);
  },

  /**
   * 函数名称：Rainier.UI.V2.CommandDelete.undo<br>
   * 函数功能：撤销命令<br>
   * 函数返回：无<br>
   * 异常信息：无<br>
   */
  undo: function () {
    var _this = this;
    if (this.deleteInfo) {
      var currentModel = this.deleteInfo.model;
      var connInfoStack = this.deleteInfo.deleteConnInfoStack.clone();
      if (currentModel instanceof Rainier.UI.V2.DeviceModel) {
        var portList = this.deleteInfo.ports.clone();
        portList.each(function (index, port) {
          currentModel.addPort(port);
        });

        var parentModel = currentModel.getParent();

        // 撤销时，修改自定义器件的图片
        currentModel.property.imageProperty.svg =
          currentModel.property.uiProperty.imageString;

        parentModel.addChildModel(currentModel);
        var uiProperty = currentModel.getProperty().uiProperty;
        currentModel.setPosition(uiProperty.x, uiProperty.y, false);

        //判断器材展示栏中是否已存在该器材，若存在则不再再次向展示栏中添加
        var className = currentModel.property.modelProperty.typeName;
        var componentName = currentModel.property.modelProperty.componentName;
        this.addUsedPart(className, componentName);
      }

      //翻转数组，逆序恢复数组中的内容
      connInfoStack.reverse();

      //恢复连线：
      connInfoStack.each(function (index, connModelInfo) {
        _this.addConnectionModel(connModelInfo);
      });
      var rootEditPart = this.context.getRootEditPart();
      rootEditPart.refreshChildren();
      //恢复树结构
      if (_this.nodeParent) {
        $("#ul-mindMap").tree("append", {
          parent: _this.nodeParent.target,
          data: [
            {
              id: _this.node.id,
              text: _this.node.text,
              state: _this.node.state,
              animate: _this.node.animate,
            },
          ],
        });
        $.each(_this.nodeChildren, function (index, child) {
          var node = $("#ul-mindMap").tree("find", child.id);
          var _node = $("#ul-mindMap").tree("find", _this.node.id);
          var nodeChildren = $("#ul-mindMap").tree("getChildren", _node.target);
          var index = nodeChildren.indexOf(node);
          if (node && index == -1) {
            var _nodeChildren = [];
            _nodeChildren.push(node);
            $("#ul-mindMap").tree("remove", node.target);
            _this.addSubTree(_nodeChildren, _node);
          }
        });
      }
      //父节点添加子信息
      var parentId = currentModel.property.modelProperty.parent;
      var parent = this.getModelById(parentId);
      if (parent) {
        var children = parent.property.modelProperty.children;
        if (children) {
          var _id = currentModel.property.modelProperty.id;
          children.push(_id);
        }
      }
    }
  },

  /**
   * 函数名称：Rainier.UI.V2.CommandAddTheme.getModelById<br>
   * 函数功能：根据主题id查询对应model<br>
   * 参数输入：无<br>
   * 参数输出：无<br>
   * 函数返回：无<br>
   * 异常信息：无<br>
   */
  getModelById: function (id) {
    var parentModel = this.editPart.getParent().getModel();
    var children = parentModel.m_aChildren;
    var model = null;
    if (children) {
      $.each(children, function (index, child) {
        var _id = child.property.modelProperty.id;
        if (_id == id) {
          model = child;
        }
      });
    }
    return model;
  },

  /**
   * 函数名称：Rainier.UI.V2.CommandDelete.addUsedPart<br>
   * 函数功能：(单个添加器件)判断器材展示栏中是否已存在该器材，若存在则不再再次向展示栏中添加<br>
   * 函数输入：className和componentName
   * 函数返回：无<br>
   * 异常信息：无<br>
   */
  addUsedPart: function (className, componentName) {
    // if(className == "OverThreeTextModelJson" || className === "TextModelJson2" || className === "TextModelJson3"){
    // 	className = "TextModelJson";
    // }
    var usedPart = {};
    usedPart.isLogic = true;
    usedPart.courseType = "Communication";
    usedPart.deviceType = "PmsModel";
    //data_part:data的一个对象
    var data_part = {};
    data_part.className = className;
    // 还未向实验台添加器件时
    if (data.length == 0) {
      if (className) {
        data_part.addCount = 1;
      }
      data.push(data_part);
      usedPart.className = data[0].className;
      usedPart.componentName = componentName;
      usedPartArray.push(usedPart);
      // console.log(data);
      // console.log(usedPartArray);
      // 实验台上已经存在器件时
    } else {
      for (var i = 0; i < data.length; i++) {
        if (data[i].className == className) {
          // console.log("已加入已使用器件数组!");
          data[i].addCount += 1;
          // console.log(data);
          return;
        }
      }
      data_part.addCount = 1;
      data.push(data_part);
      usedPart.className = data[data.length - 1].className;
      usedPart.componentName = componentName;
      usedPartArray.push(usedPart);
      // console.log(data);
      // console.log(usedPartArray);
    }
  },

  /**
   * 函数名称：draw2d.command.CommandDelete.redo<br>
   * 函数功能：重做命令<br>
   * 函数返回：无<br>
   * 异常信息：无<br>
   */
  redo: function () {
    this.execute();
  },

  /**
   * 函数名称：draw2d.command.CommandDelete.addConnectionModel<br>
   * 函数功能：恢复连线信息的添加<br>
   * 参数输入：connModelInfo:封装好的connModelInfo信息<br>
   * 参数输出：无<br>
   * 函数返回：无<br>
   * 异常信息：无<br>
   */
  addConnectionModel: function (connModelInfo) {
    var connType = connModelInfo.connType;
    var connObj = connModelInfo.connModel;
    var sourceModel = connModelInfo.sourceModel;
    var targetModel = connModelInfo.targetModel;

    //第一步：把当前连线添加进来
    var conn = connObj.connection;

    //第二步：恢复连线两端的jointModel
    if (sourceModel) {
      var jointModel = sourceModel.jointModel;
      var hybridPort = sourceModel.hybirdPort;

      var jointModelId = jointModel.getUuid();

      var jointModelParent = jointModel.getParent();
      var connJointModelIds = [];
      var connJointModels = jointModelParent.getChildren();
      connJointModels.forEach(function (
        connJointModel,
        index,
        connJointModels
      ) {
        connJointModelIds.push(connJointModel.getUuid());
      });
      //不存在当前model
      if (connJointModelIds.indexOf(jointModelId) === -1) {
        jointModel.addPort(hybridPort);
        jointModelParent.addChildModel(jointModel);
      }
    }

    if (targetModel) {
      var jointModel = targetModel.jointModel;
      var hybridPort = targetModel.hybirdPort;

      var jointModelId = jointModel.getUuid();

      var jointModelParent = jointModel.getParent();
      var connJointModelIds = [];
      var connJointModels = jointModelParent.getChildren();
      connJointModels.forEach(function (
        connJointModel,
        index,
        connJointModels
      ) {
        connJointModelIds.push(connJointModel.getUuid());
      });
      //不存在当前model
      if (connJointModelIds.indexOf(jointModelId) === -1) {
        jointModel.addPort(hybridPort);
        jointModelParent.addChildModel(jointModel);
      }
    }

    //第三步：恢复连线和sourcePort和targetPort的关联关系。
    var sourcePort = connObj.sourcePort;
    var targetPort = connObj.targetPort;
    conn.attachSourcePort(sourcePort);
    conn.attachTargetPort(targetPort);
    sourcePort.attachOutgoing(conn);
    targetPort.attachIncoming(conn);

    var connParent = conn.getParent();
    connParent.addConnection(conn);

    //		this.context.rootModel.setConnectionPortValue(sourcePort,targetPort);
  },
});
